package com.sse.deployer;

import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;

import com.sse.casa.CasaInteligenteApp;
import com.sse.casa.simulacion.ConectorBD;
import com.sse.sensor.ISensor;
import com.sse.sensor.Sensor;
import com.sse.sensor.TipoSensor;
import com.sse.sensor.impl.SensorAntena;
import com.sse.sensor.impl.SensorHumo;
import com.sse.sensor.impl.SensorIngreso;
import com.sse.sensor.impl.SensorMovimiento;
import com.sse.sensor.impl.SensorPuerta;
import com.sse.sensor.impl.SensorVentana;
import com.sse.sensor.utils.EventoUtil;

public class DeployerCore {

	private static final DeployerCore instance = new DeployerCore();

	private String sistemaCentralIP;
	private int sistemaCentralPuerto;

	private String jdbcURL;
	private String usuario;
	private String password;

	private String idCasa;
	
	

	private CasaInteligenteApp casaInteligenteApp;

	private SensorHumo sensorHumo;
	private SensorVentana sensorVentana;
	private SensorAntena sensorAntena;
	private SensorIngreso sensorIngreso;
	private SensorMovimiento sensorMovimiento;
	private SensorPuerta sensorPuerta;
	

	public static DeployerCore getInstance() {
		return instance;
	}

	/**
	 * Carga la casa especificada de la base de datos, luego realiza la conexion
	 * al sistema central.
	 * 
	 * @return
	 */
	public String[] conectar() {

		List<String> resultados = new ArrayList<String>();

		try {
			ConectorBD.setProperties(this.jdbcURL, this.usuario, this.password);
			String resultadoCasa = this.iniciarCasa(Integer.valueOf(idCasa));
			resultados.add(resultadoCasa);
			

		} catch (NumberFormatException e) {
			resultados.add("Identificador de casa no valido");
			return resultados.toArray(new String[0]);
		} catch (Throwable e) {
			resultados.add("Excepcion generada: " + e.getMessage());
			return resultados.toArray(new String[0]);

		}

//		final String mensaje = "Casa Conectada al Sistema central: ";

		return resultados.toArray(new String[0]);

	}


	/**
	 * Inicializa una casa para el experimento 3
	 * 
	 * @param casaId
	 *            Identificador de la casa.
	 * @return
	 */
	public String iniciarCasa(int casaId) {

		String resultado = "Casa No. " + casaId
				+ "  inicializada correctamente. ";

		try {
			casaInteligenteApp = new CasaInteligenteApp(casaId);
			casaInteligenteApp.setSistemaCentralHost(this.sistemaCentralIP);
			casaInteligenteApp
					.setSistemaCentrarlPuerto(this.sistemaCentralPuerto);
			
			

//			casaInteligenteApp.cargarObjetosSensores(getListaSensores());
			casaInteligenteApp.cargarObjetosSensores(getListaSensores(casaInteligenteApp.getSensores()));
			casaInteligenteApp.inicializarComunicacion();

		} catch (java.net.ConnectException e) {
			return "Imposible inicializar Comunicacion casa No. " + casaId
					+ " - Ex: " + e.getMessage();
		} catch (RuntimeException e) {
			return "Imposible inicializar casa No. " + casaId + " - RTEx: "
					+ e.getMessage();
		}

		catch (Throwable e) {
			return "Imposible inicializar casa No. " + casaId + " - Ex: "
					+ e.getMessage();
		}

		return resultado;

	}

	public String finalizarConexion(){
//		this.casaInteligenteApp.
		return "";
	}
	
	
	/**
	 * Lanza un evento particular de un sensor dado.
	 * @param sensor
	 * @param evento
	 * @return
	 */
	public String lanzarEvento(String sensor, String evento) {

		String mensaje = "Lanzado correctamente evento: ";

		try {
			if (sensor.equals("HUMO")) {

				for (Entry<Long, String> entry : EventoUtil.eventosSensorHumo
						.entrySet()) {
					if (evento.equalsIgnoreCase(entry.getValue())) {
						sensorHumo.lanzarEventoManual(entry.getKey());
						mensaje += " " + entry.getValue();
						break;
					}
				}

			} else if (sensor.equals("PUERTA")) {

				for (Entry<Long, String> entry : EventoUtil.eventosSensorPuerta
						.entrySet()) {
					if (evento.equalsIgnoreCase(entry.getValue())) {
						sensorPuerta.lanzarEventoManual(entry.getKey());
						mensaje += " " + entry.getValue();
						break;
					}
				}

			} else if (sensor.equals("ANTENA")) {

				for (Entry<Long, String> entry : EventoUtil.eventosSensorAntena
						.entrySet()) {
					if (evento.equalsIgnoreCase(entry.getValue())) {
						sensorAntena.lanzarEventoManual(entry.getKey());
						mensaje += " " + entry.getValue();
						break;
					}
				}

			} else if (sensor.equals("INGRESO")) {
				for (Entry<Long, String> entry : EventoUtil.eventosSensorIngreso
						.entrySet()) {
					if (evento.equalsIgnoreCase(entry.getValue())) {
						sensorIngreso.lanzarEventoManual(entry.getKey());
						mensaje += " " + entry.getValue();
						break;
					}
				}

			} else if (sensor.equals("MOVIMIENTO")) {
				for (Entry<Long, String> entry : EventoUtil.eventosSensorMovimiento
						.entrySet()) {
					if (evento.equalsIgnoreCase(entry.getValue())) {
						sensorMovimiento.lanzarEventoManual(entry.getKey());
						mensaje += " " + entry.getValue();
						break;
					}
				}

			} else if (sensor.equals("VENTANA")) {
				for (Entry<Long, String> entry : EventoUtil.eventosSensorVentana
						.entrySet()) {
					if (evento.equalsIgnoreCase(entry.getValue())) {
						sensorVentana.lanzarEventoManual(entry.getKey());
						mensaje += " " + entry.getValue();
						break;
					}
				}
			}
		} catch (Exception e) {
			return "Error al tratar de lanzar evento: " + evento + " Ex: "
					+ e.getMessage();
		}
		return mensaje;
	}

	/**
	 * Obtiene una lista de sensores para la prueba del experimento 33
	 * @return
	 */
//	private List<Sensor> getListaSensores() {
//
//		sensorHumo = new SensorHumo();
//		sensorHumo.setId(1);
//
//		sensorAntena = new SensorAntena();
//		sensorAntena.setId(2);
//		sensorAntena.setX(122);
//		sensorAntena.setY(746);
//
//		sensorIngreso = new SensorIngreso();
//		sensorIngreso.setId(3);
//		sensorIngreso.setX(47);
//		sensorIngreso.setY(22);
//
//		sensorMovimiento = new SensorMovimiento();
//		sensorMovimiento.setId(4);
//		sensorMovimiento.setX(100);
//		sensorMovimiento.setY(200);
//
//		sensorPuerta = new SensorPuerta();
//		sensorPuerta.setId(5);
//		sensorPuerta.setX(30);
//		sensorPuerta.setY(23);
//
//		sensorVentana = new SensorVentana();
//		sensorVentana.setId(5);
//		sensorVentana.setX(27);
//		sensorVentana.setY(57);
//
//		List<Sensor> listaSensores = new ArrayList<Sensor>();
//		listaSensores.add(sensorAntena);
//		listaSensores.add(sensorHumo);
//		listaSensores.add(sensorIngreso);
//		listaSensores.add(sensorMovimiento);
//		listaSensores.add(sensorPuerta);
//		listaSensores.add(sensorVentana);
//
//		return listaSensores;
//	}

	
	private List<Sensor> getListaSensores(List<ISensor> sensoresIniciales) {
		
		
		boolean[] sensores = new boolean[EventoUtil.tiposSensores.length] ;
		
		
		for(ISensor s : sensoresIniciales){
			
			if(s.getTipoSensor() == TipoSensor.ANTENA  && !sensores[(int) TipoSensor.ANTENA]){
				this.sensorAntena = (SensorAntena) s;
				sensores[(int) TipoSensor.ANTENA] = true;				
			}
			
			else if(s.getTipoSensor() == TipoSensor.HUMO  && !sensores[(int) TipoSensor.HUMO]){
				this.sensorHumo = (SensorHumo) s;
				sensores[(int) TipoSensor.HUMO] = true;				
			}
			
			else if(s.getTipoSensor() == TipoSensor.INGRESO  && !sensores[(int) TipoSensor.INGRESO]){
				this.sensorIngreso = (SensorIngreso) s;
				sensores[(int) TipoSensor.INGRESO] = true;				
			}
			else if(s.getTipoSensor() == TipoSensor.MOVIMIENTO && !sensores[(int) TipoSensor.MOVIMIENTO]){
				this.sensorMovimiento = (SensorMovimiento) s;
				sensores[(int) TipoSensor.MOVIMIENTO] = true;				
			}			
			else if(s.getTipoSensor() == TipoSensor.PUERTA  && !sensores[(int) TipoSensor.PUERTA]){
				this.sensorPuerta = (SensorPuerta) s;
				sensores[(int) TipoSensor.PUERTA] = true;				
			}
			else if(s.getTipoSensor() == TipoSensor.VENTANA && !sensores[(int) TipoSensor.VENTANA]){
				this.sensorVentana = (SensorVentana) s;
				sensores[(int) TipoSensor.VENTANA] = true;				
			}			
		}
		
		
		List<Sensor> listaSensores = new ArrayList<Sensor>();
		listaSensores.add(sensorAntena);
		listaSensores.add(sensorHumo);
		listaSensores.add(sensorIngreso);
		listaSensores.add(sensorMovimiento);
		listaSensores.add(sensorPuerta);
		listaSensores.add(sensorVentana);

		return listaSensores;
	}

	
	
	
	
	public String getSistemaCentralIP() {
		return sistemaCentralIP;
	}

	public void setSistemaCentralIP(String sistemaCentralIP) {
		this.sistemaCentralIP = sistemaCentralIP;
	}

	public int getSistemaCentralPuerto() {
		return sistemaCentralPuerto;
	}

	public void setSistemaCentralPuerto(int sistemaCentralPuerto) {
		this.sistemaCentralPuerto = sistemaCentralPuerto;
	}

	public String getJdbcURL() {
		return jdbcURL;
	}

	public void setJdbcURL(String jdbcURL) {
		this.jdbcURL = jdbcURL;
	}

	public String getUsuario() {
		return usuario;
	}

	public void setUsuario(String usuario) {
		this.usuario = usuario;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getIdCasa() {
		return idCasa;
	}

	public void setIdCasa(String idCasa) {
		this.idCasa = idCasa;
	}

	public CasaInteligenteApp getCasaInteligenteApp() {
		return casaInteligenteApp;
	}

	public void setCasaInteligenteApp(CasaInteligenteApp casaInteligenteApp) {
		this.casaInteligenteApp = casaInteligenteApp;
	}

}
